﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

using Framework.Graphics;
using Framework.Map;
using Framework.GameStateManagment;
using Framework.GameObjectManagment;
using Framework.GameStateManagment.GameScreens;

namespace Framework.Graphics.Light.Shadow
{
    public class LightControl
    {
        List<Light> _lights;
        private QuadRenderComponent _render;
        private ShadowmapResolver _shadowmapResolver;
        private GraphicsDevice _graphicsDevice;
        private RenderTarget2D _screenShadows;
        private RenderTarget2D _screen;
        private Texture2D _black;

        public RenderTarget2D ScreenShadows
        {
            get { return _screenShadows; }
            set { _screenShadows = value; }
        }

        public List<Light> LightsList
        {
            get { return _lights; }
            set { _lights = value; }
        }

        public GraphicsDevice GraphicsDevice
        {
            get { return _graphicsDevice; }
            set { _graphicsDevice = value; }
        }

        public QuadRenderComponent QRC
        {
            get { return _render; }
            set { _render = value; }
        }

        public void Init(GraphicsDevice GD, Game game)
        {
            _black = game.Content.Load<Texture2D>(@"Effect/Black");
            _graphicsDevice = GD;
            _render = new QuadRenderComponent(game);
            _shadowmapResolver = new ShadowmapResolver(GD, _render, ShadowmapSize.Size512, ShadowmapSize.Size512);
            _shadowmapResolver.LoadContent(game.Content);
            _screenShadows = new RenderTarget2D(GD, GD.Viewport.Width, GD.Viewport.Height * 2);
            _render.LoadContent();

            _screen = new RenderTarget2D(GD, GD.Viewport.Width, GD.Viewport.Height);
            _lights = new List<Light>();
        }

        public void Draw(RenderTarget2D shadowObjects, LightManager LM) //(TileMap map,GameObjectManager gom)
        {
            for (int i = 0; i < _lights.Count; i++)
            {
                //_lights[i].Position += Input.MovementNow();
                if (i != 0)
                {
                    _lights[i].LightArea.LightPosition = _lights[i].Position + Input.MovementNow();
                }
                else
                {

                }
                _lights[i].LightArea.BeginDrawingShadowCasters();

                //Camera.SpriteBatch.Begin();
                ////Camera.TryDrawCasters(shadowObjects, _lights[i].LightArea.ToRelativePosition(new Vector2(0,0)), Color.Black);
                ////LM.DrawShadowObjects();

                
                //Camera.SpriteBatch.End();
                DrawCasters(_lights[i].LightArea);

                //DrawCasters(_lights[i].LightArea, map,gom);
                _lights[i].LightArea.EndDrawingShadowCasters();
                _shadowmapResolver.ResolveShadows(_lights[i].LightArea.RenderTarget, _lights[i].LightArea.RenderTarget, _lights[i].Position);
            }

            _graphicsDevice.SetRenderTarget(_screenShadows);
            _graphicsDevice.Clear(Color.Black);
            Camera.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
            for (int i = 0; i < _lights.Count; i++)
            {
                Camera.TryDraw(_lights[i].LightArea.RenderTarget, _lights[i].Position+Input.Movement - _lights[i].LightArea.LightAreaSize * 0.5f, _lights[i].Color);
            }
            Camera.SpriteBatch.End();

            _graphicsDevice.SetRenderTarget(null);
            _graphicsDevice.Clear(Color.Black);

            //Camera.SpriteBatch.Begin();
            LM.BumpManager.Draw(LM.BumpColor, LM.BumpNormal, LM);
            //map.DrawGround();
            //Camera.SpriteBatch.End();

            _graphicsDevice.SetRenderTarget(null);

            BlendState blendState = new BlendState();
            blendState.ColorSourceBlend = Blend.DestinationColor;
            blendState.ColorDestinationBlend = Blend.SourceColor;

            Camera.SpriteBatch.Begin(SpriteSortMode.Immediate, blendState);
            Camera.TryDraw(_screenShadows, new Vector2(0, 0), Color.White);
            Camera.SpriteBatch.End();
            
        }

        public void Draw(RenderTarget2D shadowObjects, LightManager LM, TileMap map,GameObjectManager gom)
        {
            for (int i = 0; i < _lights.Count; i++)
            {
                //_lights[i].Position += Input.MovementNow();
                _lights[i].LightArea.LightPosition = _lights[i].Position + Input.Movement;
                _lights[i].LightArea.BeginDrawingShadowCasters();

                //Camera.SpriteBatch.Begin();
                ////Camera.TryDrawCasters(shadowObjects, _lights[i].LightArea.ToRelativePosition(new Vector2(0,0)), Color.Black);
                ////LM.DrawShadowObjects();


                //Camera.SpriteBatch.End();
                DrawCasters(_lights[i].LightArea,map,gom);

                //DrawCasters(_lights[i].LightArea, map,gom);
                _lights[i].LightArea.EndDrawingShadowCasters();
                _shadowmapResolver.ResolveShadows(_lights[i].LightArea.RenderTarget, _lights[i].LightArea.RenderTarget, _lights[i].Position);
            }

            _graphicsDevice.SetRenderTarget(_screenShadows);
            _graphicsDevice.Clear(Color.Black);
            Camera.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
            for (int i = 0; i < _lights.Count; i++)
            {
                Camera.TryDraw(_lights[i].LightArea.RenderTarget, _lights[i].Position + Input.Movement - _lights[i].LightArea.LightAreaSize * 0.5f, _lights[i].Color);
            }
            Camera.SpriteBatch.End();

            _graphicsDevice.SetRenderTarget(null);
            _graphicsDevice.Clear(Color.Black);

            //Camera.SpriteBatch.Begin();
            LM.BumpManager.Draw(LM.BumpColor, LM.BumpNormal, LM);
            //map.DrawGround();
            //Camera.SpriteBatch.End();

            _graphicsDevice.SetRenderTarget(null);

            BlendState blendState = new BlendState();
            blendState.ColorSourceBlend = Blend.DestinationColor;
            blendState.ColorDestinationBlend = Blend.SourceColor;

            Camera.SpriteBatch.Begin(SpriteSortMode.Immediate, blendState);
            Camera.TryDraw(_screenShadows, new Vector2(0, 0), Color.White);
            Camera.SpriteBatch.End();

        }

        private void DrawCasters(LightArea lightArea)//, TileMap map, GameObjectManager gom)
        {

            Camera.SpriteBatch.Begin();
            //Hindernisse für das Licht zeichnen
            //for (int y = 0; y < map.MapHeight; y++)
            //{
            //    for (int x = 0; x < map.MapWidth; x++)
            //    {
            //        Vector2 Temp = lightArea.ToRelativePosition(new Vector2(map.AllTiles[x, y].TileX * 50, map.AllTiles[x, y].TileY * 50));
            //        if (map.AllTiles[x,y].TileEnterable == false)
            //        {
            //            Camera.TryDrawCasters(_black, Temp, Color.Black);
            //        }
            //    }
            //}
            //GameObjektManager.DrawShadows(lightArea);
            //Camera.SpriteBatch.Draw(Player, lightArea.ToRelativePosition(new Vector2(512, 362)), null, Color.White, 0f, Vector2.Zero, 0.5f, SpriteEffects.None, 0f);

            //NEW -->
            //Camera.TryDrawCasters(_black, lightArea.ToRelativePosition(new Vector2(170, 25)), Color.Black);

            Camera.SpriteBatch.End();         
            
            //gom.DrawShadowObjects(lightArea);
        }

        private void DrawCasters(LightArea lightArea, TileMap map, GameObjectManager gom)
        {

            Camera.SpriteBatch.Begin();
            for (int y = 0; y < map.MapHeightPx/50; y++)
            {
                for (int x = 0; x < map.MapWidthPx/50; x++)
                {
                    Vector2 Temp = lightArea.ToRelativePosition(new Vector2(map.AllTiles[x, y].TileX * 50, map.AllTiles[x, y].TileY * 50)+Input.AllMovement);
                    if (map.AllTiles[x, y].TileEnterable == false)
                    {
                        Camera.TryDrawCasters(map.Shadows[map.AllTiles[x,y].Shadow], Temp, Color.White);
                        // Möglicher Fehler ... falsche Texturen - welche Texturen ??
                    }
                }
            }

            Camera.SpriteBatch.End();

            gom.DrawShadowObjects(lightArea);
        }
    }
}
